package cn.xdf.docscan.utils

import android.graphics.*
import android.media.Image
import android.util.Log
import androidx.camera.core.ImageProxy
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer

/**
 * 图像处理工具类
 */
object ImageUtils {
    
    private const val TAG = "ImageUtils"
    
    /**
     * 将ImageProxy转换为Bitmap
     */
    fun imageProxyToBitmap(imageProxy: ImageProxy): Bitmap? {
        return try {
            when (imageProxy.format) {
                ImageFormat.YUV_420_888 -> {
                    yuv420888ToBitmap(imageProxy)
                }
                ImageFormat.FLEX_RGBA_8888 -> {
                    rgba8888ToBitmap(imageProxy)
                }
                else -> {
                    Log.w(TAG, "不支持的图像格式: ${imageProxy.format}")
                    null
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "转换ImageProxy为Bitmap失败", e)
            null
        }
    }
    
    /**
     * 将YUV_420_888格式转换为Bitmap
     */
    private fun yuv420888ToBitmap(imageProxy: ImageProxy): Bitmap? {
        val image: Image = imageProxy.image ?: return null
        
        val yBuffer: ByteBuffer = image.planes[0].buffer
        val uBuffer: ByteBuffer = image.planes[1].buffer
        val vBuffer: ByteBuffer = image.planes[2].buffer
        
        val ySize: Int = yBuffer.remaining()
        val uSize: Int = uBuffer.remaining()
        val vSize: Int = vBuffer.remaining()
        
        val nv21 = ByteArray(ySize + uSize + vSize)
        
        // U and V are swapped
        yBuffer.get(nv21, 0, ySize)
        vBuffer.get(nv21, ySize, vSize)
        uBuffer.get(nv21, ySize + vSize, uSize)
        
        val yuvImage = YuvImage(nv21, ImageFormat.NV21, image.width, image.height, null)
        val out = ByteArrayOutputStream()
        yuvImage.compressToJpeg(Rect(0, 0, yuvImage.width, yuvImage.height), 100, out)
        val imageBytes = out.toByteArray()
        
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
    }
    
    /**
     * 将RGBA_8888格式转换为Bitmap
     */
    private fun rgba8888ToBitmap(imageProxy: ImageProxy): Bitmap? {
        val image: Image = imageProxy.image ?: return null
        val buffer: ByteBuffer = image.planes[0].buffer
        
        val bytes = ByteArray(buffer.remaining())
        buffer.get(bytes)
        
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
    }
    
    /**
     * 检查图像是否适合文档扫描
     */
    fun isSuitableForDocumentScan(bitmap: Bitmap): Boolean {
        // 检查图像尺寸
        if (bitmap.width < 640 || bitmap.height < 480) {
            Log.d(TAG, "图像尺寸太小: ${bitmap.width}x${bitmap.height}")
            return false
        }
        
        // 检查图像质量（简单的亮度检查）
        val brightness = calculateBrightness(bitmap)
        if (brightness < 0.1 || brightness > 0.9) {
            Log.d(TAG, "图像亮度不合适: $brightness")
            return false
        }
        
        // 检查图像对比度
        val contrast = calculateContrast(bitmap)
        if (contrast < 0.1) {
            Log.d(TAG, "图像对比度太低: $contrast")
            return false
        }
        
        return true
    }
    
    /**
     * 计算图像平均亮度
     */
    private fun calculateBrightness(bitmap: Bitmap): Float {
        val pixels = IntArray(bitmap.width * bitmap.height)
        bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
        
        var totalBrightness = 0f
        for (pixel in pixels) {
            val r = Color.red(pixel)
            val g = Color.green(pixel)
            val b = Color.blue(pixel)
            totalBrightness += (r + g + b) / 3f / 255f
        }
        
        return totalBrightness / pixels.size
    }
    
    /**
     * 计算图像对比度
     */
    private fun calculateContrast(bitmap: Bitmap): Float {
        val pixels = IntArray(bitmap.width * bitmap.height)
        bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
        
        var totalBrightness = 0f
        for (pixel in pixels) {
            val r = Color.red(pixel)
            val g = Color.green(pixel)
            val b = Color.blue(pixel)
            totalBrightness += (r + g + b) / 3f / 255f
        }
        
        val meanBrightness = totalBrightness / pixels.size
        
        var variance = 0f
        for (pixel in pixels) {
            val r = Color.red(pixel)
            val g = Color.green(pixel)
            val b = Color.blue(pixel)
            val brightness = (r + g + b) / 3f / 255f
            variance += (brightness - meanBrightness) * (brightness - meanBrightness)
        }
        
        return variance / pixels.size
    }
    
    /**
     * 旋转Bitmap
     */
    fun rotateBitmap(bitmap: Bitmap, degrees: Float): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(degrees)
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }
    
    /**
     * 裁剪Bitmap
     */
    fun cropBitmap(bitmap: Bitmap, left: Int, top: Int, right: Int, bottom: Int): Bitmap {
        return Bitmap.createBitmap(bitmap, left, top, right - left, bottom - top)
    }
    
    /**
     * 调整Bitmap大小
     */
    fun resizeBitmap(bitmap: Bitmap, newWidth: Int, newHeight: Int): Bitmap {
        return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true)
    }
    
    /**
     * 计算图像质量分数
     */
    fun calculateImageQuality(bitmap: Bitmap): Float {
        val brightness = calculateBrightness(bitmap)
        val contrast = calculateContrast(bitmap)
        
        // 简单的质量评分算法
        var score = 0f
        
        // 亮度评分 (0.3-0.7为最佳)
        if (brightness in 0.3..0.7) {
            score += 0.4f
        } else if (brightness in 0.2..0.8) {
            score += 0.2f
        }
        
        // 对比度评分
        if (contrast > 0.1) {
            score += 0.3f
        } else if (contrast > 0.05) {
            score += 0.15f
        }
        
        // 尺寸评分
        val minDimension = minOf(bitmap.width, bitmap.height)
        if (minDimension >= 1920) {
            score += 0.3f
        } else if (minDimension >= 1280) {
            score += 0.2f
        } else if (minDimension >= 640) {
            score += 0.1f
        }
        
        return score
    }
} 